#include "dict.h"
#include "trie.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


Dictionary::Dictionary(const char* dict_file,DictionaryType dictType)
{
	trie = new Trie();
	type = dictType;
	loadFromBin(dict_file);
}

Dictionary::~Dictionary()
{
	delete trie;
}

void Dictionary::loadDict(const char* dict_file)
{
	trie = new Trie();

	FILE * pFile;
	char string[128];
	pFile = fopen (dict_file , "r");
	if (pFile == NULL) 
	{
		perror ("Error opening file");
		getchar();
	}
	else 
	{	
		int fail=0;
		int success=0;
		fgets (string, 128, pFile);
		int i=0;
		while (!feof(pFile))
		{
			printf("\nnow reading %d line...", i++);
			/* there is a 'next-line' char at the end, remove it */
			int length = strlen(string); 
			string[length-1] = '\0';
			
			int wchar_length = strlen(string)/2 + 1;
			wchar_t * wchar_string = new wchar_t[wchar_length];
			
			CharToWchar(string, wchar_string, wchar_length);
			// if is a RMM dict, reverse the wchar_string
			if(type == Dictionary::RMM)
			{
				int length =  (wchar_length-2);
				for(int i = 0; i <= length/2; ++i)
				{
					wchar_t w = wchar_string[i];
					wchar_string[i] = wchar_string[length-i];
					wchar_string[length-i] = w;
				}
			}

			if(add(wchar_string)) ++success;
			else{
				++fail;
				printf("Fail: %s\n",string);
			}
			
			delete [] wchar_string;
			fgets (string, 128, pFile);
		}
		fclose (pFile);
		printf("\n%d words has been added into dictionary.", success);
		printf("\n%d words failed, some words are duplicated in dictionary file", fail);
	}	
}



bool Dictionary::search(wchar_t* key)
{
	return trie->retrieve(key);
}

/*
 * input string is in-order, so if it is a RMM-dictionary
 * we need reserve the key first.
 */
bool Dictionary::search(wchar_t *key, int length)
{
	wchar_t * reverseKey = new wchar_t[length+1];
	reverseKey[length] = 0;
	for(int i = 0; i< length; ++i)
	{
		reverseKey[i] = key[length-1-i];
	}
	bool result =  trie->retrieve(reverseKey);
	delete [] reverseKey;
	
	return result;
}

int Dictionary::forward(int base, wchar_t w)
{
	return trie->forward(base,w);
}

bool Dictionary::add(wchar_t *key)
{
	return trie->insert(key);
}

void Dictionary::info()
{
	trie->print_state();
}

void Dictionary::saveAsBin(const char * path)
{
	trie->saveAsDat(path);
}
void Dictionary::loadFromBin(const char * path)
{
	trie->loadFromDat(path);

}